<!--
 * @Date: 2024-03-06 11:05:16
 * @LastEditors: 陈俊宇 467724386@qq.com
 * @LastEditTime: 2024-10-22 09:12:52
-->
<template>
    <el-upload
        class="upload-file"
        :action="uploadUrl"
        :headers="headers"
        :multiple="false"
        :on-success="onSuccess"
        :on-error="onError"
        :before-upload="beforeUpload"
        :file-list="state.fileList"
        :accept="accept"
        v-loading="state.loading"
        :show-file-list="false"
    >
        <div class="cusbtn">
            <img src="@/assets/upload.png" alt="" />
            <slot>Upload file </slot>
        </div>
    </el-upload>

    <div class="file-list">
        <div class="file" v-for="(item, index) in state.fileList" :key="item.url">
            <div class="img-box">
                <img class="img" src="@/assets/chat-file.png" alt="" />
                <div class="file-type">{{ item.type }}</div>
            </div>

            <div class="name">
                <div class="text">
                    {{ item.name }}
                </div>

                <div class="size">{{ item.size }}MB</div>
            </div>

            <el-icon class="close"><Close @click="remove(index)" /></el-icon>
        </div>
    </div>
</template>

<script setup>
import { reactive, watch } from 'vue'
import { Close } from '@element-plus/icons-vue'
import { determineFileType, getImageWh, getVideoWh } from '@/utils'

const props = defineProps({
    limit: {
        type: Number,
        default: 99,
    },
    accept: {
        type: String,
        default: '',
    },
    fileList: {
        type: Array,
        default: () => {
            return []
        },
    },
})

const emit = defineEmits(['success'])

const uploadUrl = `${import.meta.env.VITE_SERVE}/resource/oss/uploadByUser`
const headers = {}
const state = reactive({
    loading: false,
    fileList: [],
})

// watch(
// 	() => props.fileList,
// 	(newVal) => {
// 		state.fileList = newVal
// 	},
// 	{ deep: true }
// )

const remove = (index) => {
    state.fileList.splice(index, 1)

    const list = state.fileList.map((e) => {
        const data = e.response.data

        return {
            name: data.fileName,
            url: data.url,
        }
    })

    emit('success', list)
}

const onSuccess = async (res, file) => {
    if (res.code == 200) {
        const fileData = res.data
        const typeIndex = fileData.fileName.lastIndexOf('.')
        const extension = fileData.fileName.substring(typeIndex + 1)
        const isMedia = file.raw.type.includes('video') ? true : false
        const image = file.raw.type.includes('image') ? true : false

        const data = {
            url: fileData.url,
            fileUrl: fileData.url,
            type: extension,
            fileType: extension,
            name: fileData.fileName,
            title: fileData.fileName,
            isMedia: isMedia,
            image:image,
            fileLength: file.size,
            size: convertFileSizeToMB(file.size),
        }

        if (determineFileType(extension) === 'image') {
            await getImageWh(file.raw)
                .then(({ width, height }) => {
                    // 这里可以做进一步的处理，比如更新Vue组件的状态
                    data.fileWidth = width
                    data.fileHeight = height
                })
                .catch((error) => {
                    console.error('Error loading Image:', error)
                })
        }

        if (determineFileType(extension) === 'video') {
            await getVideoWh(file.raw)
                .then(({ width, height, duration }) => {
                    data.fileWidth = width
                    data.fileHeight = height
                    data.duration = parseInt(duration * 1000)
                    // 进一步处理，如更新Vue组件状态
                })
                .catch((error) => {
                    console.error('Error loading video:', error)
                })
        }

        state.fileList.push(data)

        emit('success', state.fileList)
    } else {
        ElMessage({
            message: 'Upload failed. Please check the file size or re-upload.',
            type: 'error',
        })
    }

    state.loading = false
}

const beforeUpload = (rawFile) => {
    if (state.fileList.length == props.limit) {
        ElMessage({
            message: `Upload up to ${props.limit} files.`,
            type: 'error',
        })

        return false
    }

    const isLt = rawFile.size / 1024 / 1024 < 50

    if (!isLt) {
        ElMessage({
            message: `The maximum uploaded file is 50M.`,
            type: 'error',
        })
        return false
    }

    state.loading = true

    return true
}

const convertFileSizeToMB = (sizeInBytes) => {
    if (sizeInBytes < 0) {
        throw new Error('Size cannot be negative.')
    }

    const mb = sizeInBytes / (1024 * 1024)
    return mb.toFixed(2) // 返回 MB 单位的数值，保留两位小数
}

const onError = (error) => {
    ElMessage({
        message: 'Upload failed. Please check the file size or re-upload.',
        type: 'error',
    })
    state.loading = false
}
</script>

<style lang="scss" scoped>
.upload-file {
    width: 100%;
    margin-bottom: 12px;

    :deep(.el-upload) {
        width: 100%;
    }
    .cusbtn {
        width: 100%;
        height: 40px;
        background: #f8f8f8;
        border-radius: 4px;
        border: 1px solid #e4e4e4;
        line-height: 40px;
        text-align: center;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        span {
            font-size: 14px !important;
            font-weight: normal !important;
            color: #666666 !important;
        }
        img {
            width: 16px;
            height: 16px;
            margin-right: 4px;
        }
    }
}

.file-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    width: 100%;

    .file {
        width: 300px;
        min-height: 70px;
        background: #000;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px;
        background: #ffffff;
        border-radius: 4px;
        border: 1px solid #e4e4e4;
        box-sizing: border-box;
        margin-bottom: 12px;

        .img-box {
            width: 32px;
            height: 40px;
            position: relative;
            margin-right: 10px;

            .img {
                width: 100%;
                height: 100%;
            }
            .file-type {
                position: absolute;
                left: 0;
                top: 5px;
                font-size: 9px;
                color: #fff;
                height: 10px;
                line-height: 9px;
                padding: 2px 4px;
                background: #345c7c;
                border-radius: 0 2px 2px 0;
                text-align: center;
            }
        }

        .name {
            flex: 1;
            height: 40px;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            color: #333;
            line-height: normal;

            .text {
                width: 210px;
                overflow: hidden;
                white-space: nowrap;
                font-size: 12px;
                text-overflow: ellipsis;
            }

            .size {
                color: #999999;
                font-size: 10px;
            }
        }

        .close {
            cursor: pointer;
        }
    }
}
</style>
